package com.yilu.driver.base;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.is.common.base.BaseApplication;
import com.is.common.retrofitrxcache.BasicCache;
import com.is.common.retrofitrxcache.RxCacheCallAdapterFactory;
import com.is.common.utils.Futils;
import com.is.ui.netstatus.NetUtils;
import com.yilu.driver.DriverApplication;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * des:retorfit api
 * Created by Administrator on 2017/3/29 0029.
 */

public class Retrofit2Driver {

    private Retrofit retrofit;
    private static HashMap<String, Retrofit2Driver> sRetrofitManager = new HashMap<>();

    private Retrofit2Driver(String baseUrl) {
        if (retrofit == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            /**
             * 设置头
             */
            builder.addInterceptor(addHeaderInterceptor());
            /**
             * 设置公共参数
             */
            builder.addInterceptor(addQueryParameterInterceptor());
            /**
             * 设置缓存
             */
            File cacheFile = new File(BaseApplication.getAppContext().getCacheDir(), "RetrofitCache");
            Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
            builder.cache(cache).addInterceptor(new NetWorkInterceptor());
            /**
             * 设置超时
             */
            builder.connectTimeout(15, TimeUnit.SECONDS);
            builder.readTimeout(20, TimeUnit.SECONDS);
            builder.writeTimeout(20, TimeUnit.SECONDS);
            /**
             * 错误重连
             */
            builder.retryOnConnectionFailure(true);

            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder.addInterceptor(logging);
            /**
             * okhttp3
             */
            OkHttpClient client = builder.build();
            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").serializeNulls().create();
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    // .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .addCallAdapterFactory(RxCacheCallAdapterFactory.create(BasicCache.fromCtx(BaseApplication.getAppContext()), false))//分开读取网络、缓存
                    .client(client)
                    .build();
        }
    }

    public static <T> T getDefault(Class<T> cls) {
        HashMap<String, Object> hash = Futils.geBaseUrlValue(cls);
        String url = hash.get("host").toString() + hash.get("port").toString();
        String url_key = Futils.getMD5(url);
        Retrofit2Driver retrofitManager = sRetrofitManager.get(url_key);
        if (retrofitManager == null) {
            retrofitManager = new Retrofit2Driver(url);
            sRetrofitManager.put(url_key, retrofitManager);
        }
        return retrofitManager.retrofit.create(cls);
    }

    /**
     * 设置头
     */
    private static Interceptor addHeaderInterceptor() {
        Interceptor headerInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request originalRequest = chain.request();
                Request.Builder requestBuilder = originalRequest.newBuilder()
                        // Provide your custom header here
                        .header("Content-Type", "application/json")
                        .header("Accept", "application/json")
//                        .header("apikey", "afd4c07e56a3f661aac83c1dc8e0fe7f")
                        .method(originalRequest.method(), originalRequest.body());
                Request request = requestBuilder.build();
                return chain.proceed(request);
            }
        };
        return headerInterceptor;
    }

    /**
     * 设置公共参数
     */
    private static Interceptor addQueryParameterInterceptor() {
        Interceptor addQueryParameterInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request originalRequest = chain.request();
                Request request;
                HttpUrl modifiedUrl = originalRequest.url().newBuilder()
                        // Provide your custom parameter here
                        .addQueryParameter("platform", "android")
                        .addQueryParameter("version", "1.0.0")
                        .build();
                request = originalRequest.newBuilder().url(modifiedUrl).build();
                return chain.proceed(request);
            }
        };
        return addQueryParameterInterceptor;
    }

    class NetWorkInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            //无网络时强制使用缓存
            if (!NetUtils.isNetworkConnected(DriverApplication.getAppContext())) {
                request = request.newBuilder()
                        .cacheControl(CacheControl.FORCE_CACHE)
                        .build();
            }

            Response response = chain.proceed(request);

            if (NetUtils.isNetworkConnected(DriverApplication.getAppContext())) {
                // 有网络时，设置超时为0
                int maxStale = 0;
                response.newBuilder()
                        .header("Cache-Control", "public, max-age=" + maxStale)
                        .removeHeader("Pragma")// 清除头信息，因为服务器如果不支持，会返回一些干扰信息，不清除下面无法生效
                        .build();
            } else {
                // 无网络时，设置超时为3周
                int maxStale = 60 * 60 * 24 * 21;
                response.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .removeHeader("Pragma")
                        .build();
            }

            return response;
        }
    }

}
